﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Dukou.DTO
{
    /// <summary>
    /// 对象解析器
    /// </summary>
    [Serializable]
    public class ObjectParser
    {
        /// <summary>
        /// 对象解析器缓存
        /// </summary>
        protected static IDictionary<Type, ObjectParser> ParserCache = new Dictionary<Type, ObjectParser>();

        /// <summary>
        /// 解析一般对象返回传输对象
        /// </summary>
        /// <typeparam name="T">传输对象</typeparam>
        /// <typeparam name="K">一般对象</typeparam>
        /// <typeparam name="P">对象解析器</typeparam>
        /// <param name="k">需要解析的对象</param>
        /// <param name="caches">临时缓存</param>
        /// <param name="depth">深度</param>
        /// <returns>传输对象</returns>
        public static T Parse<T, K, P>(K k, IDictionary<string, ObjectCache> caches, int depth)
            where T : IUniqueIdentifier
            where K : IUniqueIdentifier
            where P : ObjectParser, new()
        {
            ObjectParser<T, K> parser = GetParser<T, K>(typeof(P));

            return parser.Parse(k, caches, depth);
        }

        /// <summary>
        /// 解析传输对象返回一般对象
        /// </summary>
        /// <typeparam name="T">传输对象</typeparam>
        /// <typeparam name="K">一般对象</typeparam>
        /// <typeparam name="P">对象解析器</typeparam>
        /// <param name="t">需要解析的对象</param>
        /// <param name="caches">临时缓存</param>
        /// <param name="depth">深度</param>
        /// <returns>一般对象</returns>
        public static K Parse<T, K, P>(T t, IDictionary<string, ObjectCache> caches, int depth)
            where T : IUniqueIdentifier
            where K : IUniqueIdentifier
            where P : ObjectParser, new()
        {
            ObjectParser<T, K> parser = GetParser<T, K>(typeof(P));

            return parser.Parse(t, caches, depth);
        }

        /// <summary>
        /// 解析一般对象列表返回传输对象列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="P"></typeparam>
        /// <param name="ks"></param>
        /// <param name="caches"></param>
        /// <param name="depth"></param>
        /// <returns></returns>
        public static IList<T> Parse<T, K, P>(IList<K> ks, IDictionary<string, ObjectCache> caches, int depth)
            where T : IUniqueIdentifier
            where K : IUniqueIdentifier
            where P : ObjectParser, new()
        {
            IList<T> ts = new List<T>();
            if (ks == null)
            {
                return ts;
            }
            ObjectParser<T, K> parser = GetParser<T, K>(typeof(P));
            foreach (var item in ks)
            {
                T t = parser.Parse(item, caches, depth);
                if (!object.Equals(default(T), t))
                {
                    ts.Add(t);
                }
            }
            return ts;
        }

        /// <summary>
        /// 解析传输对象列表返回一般对象列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="P"></typeparam>
        /// <param name="ts"></param>
        /// <param name="caches"></param>
        /// <param name="depth"></param>
        /// <returns></returns>
        public static IList<K> Parse<T, K, P>(IList<T> ts, IDictionary<string, ObjectCache> caches, int depth)
            where T : IUniqueIdentifier
            where K : IUniqueIdentifier
            where P : ObjectParser, new()
        {
            IList<K> ks = new List<K>();
            if (ts == null)
            {
                return ks;
            }
            ObjectParser<T, K> parser = GetParser<T, K>(typeof(P));
            foreach (var item in ts)
            {
                K k = parser.Parse(item, caches, depth);
                if (!object.Equals(default(K), k))
                {
                    ks.Add(k);
                }
            }
            return ks;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="K"></typeparam>
        /// <param name="type"></param>
        /// <returns></returns>
        private static ObjectParser<T, K> GetParser<T, K>(Type type)
            where T : IUniqueIdentifier
            where K : IUniqueIdentifier
        {
            ObjectParser parser = null;
            if (!ParserCache.TryGetValue(type, out parser))
            {
                parser = (ObjectParser)Activator.CreateInstance(type);
                ParserCache.Add(type, parser);
            }

            return (ObjectParser<T, K>)parser;
        }
    }

}
